package channel

import (
	"fmt"
	"strings"

	"github.com/project-flogo/core/activity"
	"github.com/project-flogo/core/data/metadata"
)

func init() {
	_ = activity.Register(&Activity{}, New)
}

var activityMd = activity.ToMetadata(&Input{}, &Output{}, &Settings{})

// Activity is an Activity that is used to publish some data on a channel
// inputs : {channel, data}
// outputs: none
type Activity struct {
	initial int64
	count   int64
}

func New(ctx activity.InitContext) (activity.Activity, error) {
	settings := Settings{}
	err := metadata.MapToStruct(ctx.Settings(), &settings, true)
	if err != nil {
		return nil, err
	}
	act := Activity{
		initial: settings.Initial,
		count:   settings.Initial,
	}
	return &act, nil
}

// Metadata returns the activity's metadata
func (a *Activity) Metadata() *activity.Metadata {
	return activityMd
}

// Eval publishes the data  on the specified channel
func (a *Activity) Eval(ctx activity.Context) (done bool, err error) {
	input := &Input{}
	err = ctx.GetInputObject(input)
	if err != nil {
		return false, err
	}

	op := strings.ToUpper(input.Op)
	switch op {
	case "INC":
		{
			a.count = a.count + 1
			break
		}
	case "RESET":
		{
			a.count = a.initial
			break
		}
	default:
		{
			return true, fmt.Errorf("invalid op: %s", input.Op)
		}
	}
	ctx.Logger().Debugf("op = %s, count = %d", op, a.count)

	output := Output{
		Count: a.count,
	}
	err = ctx.SetOutputObject(&output)

	return true, err
}
